package cn.wolfcode.p2p.business.service.impl;

import cn.wolfcode.p2p.Exception.ErrorCode;
import cn.wolfcode.p2p.base.domain.Account;
import cn.wolfcode.p2p.base.domain.LoginInfo;
import cn.wolfcode.p2p.base.query.CreditTransferQueryObject;
import cn.wolfcode.p2p.base.service.IAccountService;
import cn.wolfcode.p2p.business.domain.BidRequest;
import cn.wolfcode.p2p.business.domain.CreditTransfer;
import cn.wolfcode.p2p.business.mapper.CreditTransferMapper;
import cn.wolfcode.p2p.business.service.IAccountFlowService;
import cn.wolfcode.p2p.business.service.IBidRequestService;
import cn.wolfcode.p2p.business.service.ICreditTransferService;
import cn.wolfcode.p2p.business.service.IPaymentScheduleDetailService;
import cn.wolfcode.p2p.util.AssertUtil;
import cn.wolfcode.p2p.util.Constant;
import cn.wolfcode.p2p.util.PageResult;
import cn.wolfcode.p2p.util.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class CreditTransferServiceImpl implements ICreditTransferService {
    @Autowired
    private CreditTransferMapper creditTransferMapper;
    @Autowired
    private IPaymentScheduleDetailService paymentScheduleDetailService;
    @Autowired
    private IBidRequestService bidRequestService;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private IAccountFlowService accountFlowService;

    @Override
    public PageResult queryCanCredittransfer(CreditTransferQueryObject qo) {
        int count = creditTransferMapper.queryForCount(qo);
        if (count == 0) {
            return PageResult.empty(qo.getPageSize());
        }
        int totalPage = count % qo.getPageSize() == 0 ? count / qo.getPageSize() : count / qo.getPageSize() + 1;
        if(totalPage < qo.getCurrentPage()){
            qo.setCurrentPage(totalPage);
        }
        List<CreditTransfer> listData = creditTransferMapper.queryForList(qo);
        return new PageResult(listData,count,qo.getCurrentPage(),qo.getPageSize());

    }

    /**
     * 投标对象id
     * @param bidId
     */
    @Override
    public void credittransfer(Long[] bidId) {
        LoginInfo user = UserContext.getLoginInfo();
        List<CreditTransfer> creditTransfers = creditTransferMapper.selectCredittransfer(bidId, user.getId(), false);
        for (CreditTransfer creditTransfer : creditTransfers) {
            creditTransfer.setBidRequestState(Constant.BIDREQUEST_STATE_BIDDING);
            creditTransfer.setTransFrom(user);
            creditTransfer.setPublishDate(new Date());
            creditTransferMapper.insert(creditTransfer);
            paymentScheduleDetailService.updateTransferStateByBidIdAndUserId(creditTransfer.getBidId(),user.getId(),true);
        }
    }

    @Override
    public PageResult queryCreditTransferForPage(CreditTransferQueryObject qo) {
        int count = creditTransferMapper.selectForCount(qo);
        if (count == 0) {
            return PageResult.empty(qo.getPageSize());
        }
        int totalPage = count % qo.getPageSize() == 0 ? count / qo.getPageSize() : count / qo.getPageSize() + 1;
        if(totalPage < qo.getCurrentPage()){
            qo.setCurrentPage(totalPage);
        }
        List<CreditTransfer> listData = creditTransferMapper.selectCreditTransferForList(qo);
        return new PageResult(listData,count,qo.getCurrentPage(),qo.getPageSize());

    }

    /**
     * 认购
     * @param id 债权转让对象模型
     */
    @Override
    public void subscribe(Long id) {
        //判断当前用户是否为借款人或转让人
        LoginInfo currentUser = UserContext.getLoginInfo();
        CreditTransfer creditTransfer = creditTransferMapper.selectByPrimaryKey(id);
        BidRequest bidRequest = bidRequestService.getBidRequestById(creditTransfer.getBidRequestId());
        AssertUtil.instance()
                .isFalse(currentUser.getId().longValue() == bidRequest.getCreateUser().getId().longValue(), ErrorCode.BORROWER_CANNOT_SUBSCRIBE)
                .isFalse(currentUser.getId().longValue() == creditTransfer.getTransFrom().getId().longValue(),ErrorCode.THE_TRANSFEROR_CANNOT_SUBSCRIBE)
        //判断当前的债权标是否处在招标中
                .isFalse(creditTransfer.getBidRequestState().intValue() != Constant.BIDREQUEST_STATE_BIDDING,ErrorCode.CREDITS_CANNOT_BE_SUBSCRIBED);
        //判断当前余额是否充足
        BigDecimal bidRequestAmount = creditTransfer.getBidRequestAmount();
        Account currentUserAccount = accountService.getAccount(currentUser.getId());
        AssertUtil.instance().isFalse(currentUserAccount.getUsableAmount().compareTo(bidRequestAmount)<0,ErrorCode.INSUFFICIENT_AMOUNT_CANNOT_BE_SUBSCRIBED);

        //转让人
        LoginInfo transFromUser = creditTransfer.getTransFrom();
        Account transFromUserAccount = accountService.getAccount(transFromUser.getId());
            //可用余额增加
        transFromUserAccount.addUsableAmount(bidRequestAmount);
            //产生收取转让债权标流水
        accountFlowService.createReceiveCreditTransferFlow(transFromUserAccount,bidRequestAmount,creditTransfer.getBidRequestTitle(),creditTransfer.getRemainMonthIndex());
            //待收本金减少
        transFromUserAccount.setUnReceivePrincipal(transFromUserAccount.getUnReceivePrincipal().subtract(bidRequestAmount));
            //待收利息减少
        transFromUserAccount.setUnReceiveInterest(transFromUserAccount.getUnReceivePrincipal().subtract(creditTransfer.getRemainInterest()));
        accountService.update(transFromUserAccount);
            //
        //接手人
            //可用余额减少
        currentUserAccount.subtractUsableAmount(bidRequestAmount);
            //产生成功认购流水
        accountFlowService.createSubscribeSuccess(currentUserAccount,bidRequestAmount,creditTransfer.getBidRequestTitle(),creditTransfer.getRemainMonthIndex());
            //待收本金增加
        currentUserAccount.setUnReceivePrincipal(currentUserAccount.getUnReceivePrincipal().add(bidRequestAmount));
            //待收利息增加
        currentUserAccount.setUnReceiveInterest(currentUserAccount.getUnReceiveInterest().add(creditTransfer.getRemainInterest()));
        accountService.update(currentUserAccount);
        //收款计划
            //将还款人的id设置为接收人
            //将该认购的债权标所对应的还款计划对象的状态设置为正常状态
        paymentScheduleDetailService.updateTransferStateAndTranToByBidIdAndUserId(creditTransfer.getBidId(),transFromUser.getId(),currentUser.getId(),false);
        //债权标对象
            //设置债权标的状态为已认购
            creditTransfer.setBidRequestState(Constant.BIDREQUEST_STATE_COMPLETE_PAY_BACK);
            //设置债权标的接手人
            creditTransfer.setTransTo(currentUser);
            //设置债权标的认购日期
            creditTransfer.setTransDate(new Date());
            update(creditTransfer);
    }

    @Override
    public  void update(CreditTransfer creditTransfer) {
        AssertUtil.instance().isFalse(creditTransferMapper.updateByPrimaryKey(creditTransfer) == 0,ErrorCode.SUBSCRIPTION_FAILED);
    }

    @Override
    public CreditTransfer getCreditTransferByBidIdAndState(Long bidId, int bidrequestState) {
        return creditTransferMapper.selectCreditTransferByBidIdAndState(bidId,bidrequestState);
    }
}
